from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models

from itsdangerous import TimedJSONWebSignatureSerializer, BadData


# Create your models here.
from meiduo_mall.utils.models import BaseModel


class User(AbstractUser):
    '''自定义用户模型类'''

    # 在自定义模型类中添加手机号
    mobile = models.CharField(max_length=11,unique=True,verbose_name='手机号')

    # 新增email_active字段,保存邮箱是否激活
    email_active = models.BooleanField(default=False,verbose_name='邮箱验证状态')

    # 新增
    default_address = models.ForeignKey('Address',
                                        related_name='users',
                                        null=True,
                                        blank=True,
                                        on_delete=models.SET_NULL,
                                        verbose_name='默认地址')


    # 对当前表进行相关设置
    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

    def generate_verify_email_url(self):
        '''
        生产邮箱验证连接
        :return:
        '''

        # 有效期: 1天
        serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY,
                                                     expires_in=60 * 60 * 24)

        # 拼接参数
        data = {'user_id': self.id, 'email': self.email}

        token = serializer.dumps(data).decode()

        verify_url = settings.EMAIL_VERIFY_URL + '?token=' + token

        return verify_url


    @staticmethod
    def check_verify_email_token(token):
        '''
        验证邮箱
        :param token:
        :return:
        '''

        # 调用 itsdangerous 类,生成对象
        # 邮件验证链接有效期：一天
        serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY,
                                        expires_in=60 * 60 * 24)

        try:
            # 解析传入的 token 值, 获取数据 data
            data = serializer.loads(token)
        except BadData:
            # 如果传入的 token 中没有值, 则报错
            return None
        else:
            # 如果有值, 则获取
            user_id = data.get('user_id')
            email = data.get('email')

        try:
            # 获取到值之后, 尝试从 User 表中获取对应的用户
            user = User.objects.get(id= user_id,email=email)

        except User.DoesNotExist:
            # 如果用户不存在, 则返回 None
            return None
        else:
            # 如果存在则直接返回
            return user


class Address(BaseModel):
    '''收货地址类'''

    user = models.ForeignKey(User,
                             on_delete=models.CASCADE,
                             related_name='addresses',
                             verbose_name='用户')
    province = models.ForeignKey('areas.Area',
                                 on_delete=models.PROTECT,
                                 related_name='province_addresses',
                                 verbose_name='省')
    city = models.ForeignKey('areas.Area',
                             on_delete=models.PROTECT,
                             related_name='city_addresses',
                             verbose_name='市')
    district = models.ForeignKey('areas.Area',
                                 on_delete=models.PROTECT,
                                 related_name='district_address',
                                 verbose_name='区')
    title = models.CharField(max_length=20, verbose_name='地址名称')
    receiver = models.CharField(max_length=20, verbose_name='收货人')
    place = models.CharField(max_length=50, verbose_name='地址')
    mobile = models.CharField(max_length=11, verbose_name='手机')
    tel = models.CharField(max_length=20,
                           null=True,
                           blank=True,
                           default='',
                           verbose_name='固定电话')

    email = models.CharField(max_length=30,
                             null=True,
                             blank=True,
                             default='',
                             verbose_name='电子邮箱')

    is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_address'
        verbose_name = '用户地址'
        verbose_name_plural = verbose_name
        ordering = ['-update_time']